package proceso.carga.malla;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringTokenizer;


import modelo.red.Atributo;
import modelo.red.AtributoMalla;
import modelo.red.EsteOeste;
import modelo.red.Malla;
import modelo.red.NorteSur;
import modelo.red.ValorAtributo;

import org.hibernate.Session;

public class LectorMallaSurfer {
	private String archivoDeEntrada;
	private String razon = "";
	private Malla malla;
	private String nombreMalla;
	private String descripcion;
	private Session sess;
	private Atributo atributo;
	private boolean mallaNueva;
	
	
	
	public Malla getMalla() {
		return malla;
	}

	public void setMalla(Malla malla) {
		this.malla = malla;
	}

	public Session getSess() {
		return sess;
	}

	public void setSess(Session sess) {
		this.sess = sess;
	}


	public String getArchivoDeEntrada() {
		return archivoDeEntrada;
	}

	public void setArchivoDeEntrada(String archivoDeEntrada) {
		this.archivoDeEntrada = archivoDeEntrada;
	}
	

	public String getNombreMalla() {
		return nombreMalla;
	}

	public void setNombreMalla(String nombreMalla) {
		this.nombreMalla = nombreMalla;
	}

	public Atributo getAtributo() {
		return atributo;
	}

	public String getRazon() {
		return razon;
	}

	public void setRazon(String razon) {
		this.razon = razon;
	}
	
	public void setAtributo(Atributo atributo) {
		this.atributo = atributo;
	}
	
	
	public boolean isMallaNueva() {
		return mallaNueva;
	}

	public void setMallaNueva(boolean mallaNueva) {
		this.mallaNueva = mallaNueva;
	}

	public boolean leerArchivo() {
		File arch;
		FileReader lectorArch;
		BufferedReader lectorBuffer;
		String linea;
		StringTokenizer tokens;
		int nroCol;
		int nroFil;
		long contadorTokens = 0;
		double esteMin;
		double esteMax;
		double norteMin;
		double norteMax;
		double z;
		double cotaMin;
		double cotaMax;
		
		ValorAtributo punto;
		AtributoMalla atributoMalla;
		
		arch = new File(archivoDeEntrada);
		if(!arch.isFile()){
			razon = "El archivo no existe";
			return false;
		}
		try {
			lectorArch = new FileReader(arch);
			lectorBuffer = new BufferedReader(lectorArch);
			try {
				linea = lectorBuffer.readLine();
				// encabezado de ()archivo
				System.out.println("Encabezado de archivo codigo surfer");
				descripcion = linea;
				linea = lectorBuffer.readLine();
				tokens = new StringTokenizer(linea);
				nroCol = Integer.parseInt(tokens.nextToken());
				nroFil = Integer.parseInt(tokens.nextToken());

				System.out.println("nro de col " + nroCol + " nro de filas " + nroFil);
				linea = lectorBuffer.readLine();
				System.out.println(linea);
				tokens = new StringTokenizer(linea);
				esteMin = Double.parseDouble(tokens.nextToken());
				esteMax = Double.parseDouble(tokens.nextToken());
				
				linea = lectorBuffer.readLine();
				System.out.println(linea);
				tokens = new StringTokenizer(linea);
				norteMin = Double.parseDouble(tokens.nextToken());
				norteMax = Double.parseDouble(tokens.nextToken());
				linea = lectorBuffer.readLine();
				System.out.println(linea);

				if(mallaNueva){
					malla = new Malla();
					malla.inicializarListaPunto();
					malla.setDescripcion(descripcion);
					malla.setNombre(nombreMalla);
					malla.setDimension(2);
					malla.setNroCol(nroCol);
					malla.setNroFil(nroFil);
					malla.setEsteMin(esteMin);	
					malla.setEsteMax(esteMax);
					malla.setNorteMin(norteMin);
					malla.setNorteMax(norteMax);
					malla.setNombre(nombreMalla);
				}
				else {
					if(nroCol != malla.getNroCol() || nroCol != malla.getNroCol() || Math.abs(malla.getEsteMin() - esteMin ) > .1 
							|| Math.abs(malla.getEsteMax() - esteMax ) > .1 || Math.abs(malla.getNorteMin() - norteMin ) > .1 
							|| Math.abs(malla.getNorteMax() - norteMax ) > .1) {
						razon += "Los valores de las mallas son distintos";
						return false;
					}
				}
					// colocar los valores de cota 
				
				atributoMalla = new AtributoMalla();
				atributoMalla.setMalla(malla);
				atributoMalla.setAtributo(atributo);
				
				malla.inicializarAtributoMalla();
				malla.agregarAtributoMalla(atributoMalla);
				tokens = new StringTokenizer(linea);
				malla.getListaAtributo().get(0).setValorMax(Double.parseDouble(tokens.nextToken()));
				malla.getListaAtributo().get(0).setValorMax(Double.parseDouble(tokens.nextToken()));
				cotaMin = malla.getListaAtributo().get(0).getValorMin();
				cotaMax = malla.getListaAtributo().get(0).getValorMax();
				
				
				double deltaNorte = ( double)(malla.getNorteMax()-malla.getNorteMin()) /(nroFil - 1);
				double deltaEste = ( double)(malla.getEsteMax()-malla.getEsteMin()) /(nroCol - 1);

				System.out.println("Delta Norte " + deltaNorte + "Delta Este " + deltaEste);
				// Inicializar los dos ejes	
				if(mallaNueva) {
					malla.inicializarEjeNorteSur();
					double valor = malla.getNorteMin();
					for(int i = 0; i<nroFil; i++){
						NorteSur puntoEjeNS = new NorteSur();
						puntoEjeNS.setValor(valor);
						puntoEjeNS.setMalla(malla);
						malla.agregarPuntoEjeNorteSur(puntoEjeNS);
						valor +=deltaNorte;
					}
					malla.inicializarEjeEsteOeste();
					valor = malla.getEsteMin();
					for(int i = 0; i<nroCol; i++){
						EsteOeste puntoEjeEO = new EsteOeste();
						puntoEjeEO.setValor(valor);
						puntoEjeEO.setMalla(malla);
						malla.agregarPuntoEjeEsteOeste(puntoEjeEO);
						valor +=deltaEste;
					}
				}
				int conFil = 0;
				int conCol = 0;
				int contLinea = 0;

				
				
//				System.out.println("Iniciando lectura de datos");
				
				boolean validez = true;
				int cantTokens;
				while(lectorBuffer.ready() && validez){
					linea = lectorBuffer.readLine();
					contLinea++;
					tokens = new StringTokenizer(linea);
					cantTokens = tokens.countTokens(); 
					if(cantTokens == 0 || cantTokens == 10 || cantTokens == nroCol%10) {
						contadorTokens += cantTokens;
						while(tokens.hasMoreElements()){
							z = Double.parseDouble(tokens.nextToken());
							if(z>=cotaMin && z<= cotaMax) {
								punto = new ValorAtributo();
								punto.setMalla(malla);
								punto.setAtributo(atributoMalla);
								punto.setNorte(malla.getEjeNorteSur().get(conFil));
								punto.setEste(malla.getEjeEsteOeste().get(conCol));
								punto.setValor(z);
								malla.agregarPunto(punto);
							}
							conCol++;
							if(conCol == nroCol){
								conCol = 0;
//								System.out.println("Leyendo fila " + conFil);
								conFil++;
							}
						}
					}
					else{
						validez = false;
						razon += "error en numero de tokens ";
						razon += " linea de datos " + contLinea;
						return false;
					}

				}
				if(nroFil*nroCol != contadorTokens) {
					razon += "Cantidad de Tokens leidos distinta a nroCol * nroFil";
					System.out.println(" nroFil * nroCol = " + nroFil*nroCol + " Tokens " + contadorTokens);
					return false;
				}
				
				
			} catch (IOException e) {
				e.printStackTrace();
				razon = "Error en la lectura";
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			razon = "No se pudo abrir el archivo";
			return false;
		}
		
		return true;

	}


	

}

